package demo;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class IndexWriterDemo {
    //存放索引文件的位置，即索引库
	static String indexpath = "D:/mylucene/luceneIndex";
	//词法分析器
    static Analyzer analyzer = new StandardAnalyzer();
	
	/** 
     * 将即将检索的资源写入索引库 
     * @param writer 
     * @throws Exception 
     */  
    public void buildDocs(List<User> list) throws Exception {  
    	///本地文件存储
    	Directory directory=FSDirectory.open(Paths.get(indexpath));
        //内存存储：优点速度快，缺点程序退出数据就没了，所以记得程序退出时保存索引库，与FSDirectory结合使用
        //由于此处只暂时保存在内存中，程序退出时没进行索引库保存，因此在搜索时程序会报错
        //Directory directory=new RAMDirectory();
        //IndexWriterConfig，据官方文档介绍，是对indexWriter的配置，其中包含了两个参数，第一个是目前的版本，第二个是词法分析器Analyzer。最新5.0已经不需要版本号，3.x和4.x需要！
        IndexWriterConfig config = new IndexWriterConfig(analyzer);  
        IndexWriter writer = new IndexWriter(directory,config);  

        //writer.deleteAll();
        //得到数据资源 
        //List<User> list = DataUtil.getUsers(); 
        
        System.out.println("buildDocs()->总人数为 :"+list.size());  
        //存放数据
        for(User user :list){  
        	 //Document存放经过组织后的数据源，只有转换为Document对象才可以被索引和搜索到
            Document doc = new Document();//创建索引库的文档  
            doc.add(new TextField("id",String.valueOf(user.getId()),Store.YES));
            doc.add(new TextField("name",user.getName(),Store.YES)); 
            doc.add(new TextField("age",String.valueOf(user.getAge()),Store.YES));
            doc.add(new TextField("sex",user.getSex(),Store.YES));  
            doc.add(new TextField("birthday",String.valueOf(user.getBirthday()),Store.YES));  
            //将文档写入索引库
            writer.addDocument(doc);  
        }  
        
        int count =writer.numDocs();  
        //关闭IndexWriter,提交创建内容
        writer.close();  
        System.out.println("buildDocs()->存入索引库的数量："+count);  
    }  
    
    /**
     * 清空索引
     * @throws IOException 
     * 
     */
    public void delDocs() throws IOException{
    	Directory directory=FSDirectory.open(Paths.get(indexpath));
    	 IndexWriterConfig config = new IndexWriterConfig(analyzer);  
         IndexWriter writer = new IndexWriter(directory,config);  
         //清空索引库里已存在的文档（document）  
         writer.deleteAll();
         writer.close(); 
    }
    
    /** 
     * 从索引库中搜索你要查询的数据 
     * @param searcher 
     * @throws IOException 
     */  
    public void searcherDocs() throws IOException{  
    	Directory directory=FSDirectory.open(Paths.get(indexpath));
    	IndexReader reader = DirectoryReader.open(directory);  
    	IndexSearcher searcher =new IndexSearcher(reader);  
    	List articleList = new ArrayList();
    	
    	 // 创建一个排序对象，其中SortField构造方法中，第一个是排序的字段，第二个是指定字段的类型，第三个是是否升序排列，true：升序，false：降序。
        // Sort sort = new Sort(new SortField("age", Type.STRING, false));
         //sort = Sort.INDEXORDER;// 评分降序排列
         
         Sort sort = new Sort();
         sort.setSort(new SortField("id",SortField.Type.DOC,true));//true为降序,false为升序
         
        Term term =new Term("sex", "man");//查询条件，意思是我要查找性别为“man”的人  
        TermQuery query =new TermQuery(term);  
         
         //TopDocs docs = searcher.search(new TermQuery(new Term("sex", "man")), null, 100, sort, true, true);
         
         //TopDocs topDocs = indexSearcher.search(query, 5, sort);
        TopDocs docs =searcher.search(query, 3, sort);//查找  
        System.out.println("searcherDoc()->男生人数："+docs.totalHits);  
        for(ScoreDoc doc:docs.scoreDocs){//获取查找的文档的属性数据  
            int docID=doc.doc;  
            Document document =searcher.doc(docID);  
            String str="ID:"+document.get("id")+",姓名："+document.get("name")+"，性别："+document.get("sex");  
            System.out.println("人员信息:"+str);  
        }  
    }  
}
